﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cesave.Domain.PermisosModule.Entities;
using Cesave.Infrastructure.Data.Core;
using Cesave.Domain.PermisosModule.Contracts.Juntas;
using Cesave.Infrastructure.Data.PermisosModule.Context;
using Cesave.Infrastructure.CrossCutting.Logging;
using Cesave.Domain.Core.Specification;

namespace Cesave.Infrastructure.Data.PermisosModule.Repositories
{
	/// <summary>
	/// 
	/// </summary>
	public class JuntaRepository
		: GenericRepositoryEx<Junta>, IJuntaRepository
	{
		#region Constructor

		/// <summary>
		/// 
		/// </summary>
		/// <param name="context"></param>
		/// <param name="traceManager"></param>
		public JuntaRepository(IPermisosModuleContext context, ITraceManager traceManager)
			: base(context, traceManager)
		{
		}

		#endregion

		#region IJuntaRepository Members

		/// <summary>
		/// 
		/// </summary>
		/// <param name="juntasByEstadoSpecification"></param>
		/// <returns></returns>
		public IEnumerable<Junta> FindJuntasByEstadoSpecification(JuntasByEstadoSpecification juntasByEstadoSpecification)
		{
			if (juntasByEstadoSpecification == null)
				throw new ArgumentNullException("juntasByEstadoSpecification");
			return GetFilteredElements(juntasByEstadoSpecification.SatisfiedBy(), junta => junta.Nombre, true);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="juntasByEstadoSpecification"></param>
		/// <param name="status"></param>
		/// <returns></returns>
		public IEnumerable<Junta> FindJuntasByEstadoAndStatusSpecification(JuntasByEstadoSpecification juntasByEstadoSpecification, bool status = true)
		{
			if (juntasByEstadoSpecification == null)
				throw new ArgumentNullException("juntasByEstadoSpecification");
			Specification<Junta> juntasSpecification = new TrueSpecification<Junta>();
			juntasSpecification &= juntasByEstadoSpecification;
			juntasSpecification &= new JuntasByStatusSpecification(status);
			return GetFilteredElements(juntasSpecification.SatisfiedBy(), junta => junta.Nombre, true);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="juntasByDistritoSpecification"></param>
		/// <returns></returns>
		public IEnumerable<Junta> FindJuntasByDistritoSpecification(JuntasByDistritoSpecification juntasByDistritoSpecification)
		{
			if (juntasByDistritoSpecification == null)
				throw new ArgumentNullException("juntasByDistritoSpecification");
			return GetFilteredElements(juntasByDistritoSpecification.SatisfiedBy(), junta => junta.Nombre, true);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="juntasByDistritoSpecification"></param>
		/// <param name="status"></param>
		/// <returns></returns>
		public IEnumerable<Junta> FindJuntasByDistritoAndStatusSpecification(JuntasByDistritoSpecification juntasByDistritoSpecification, bool status = true)
		{
			if (juntasByDistritoSpecification == null)
				throw new ArgumentNullException("juntasByDistritoSpecification");
			Specification<Junta> juntasSpecification = new TrueSpecification<Junta>();
			juntasSpecification &= juntasByDistritoSpecification;
			juntasSpecification &= new JuntasByStatusSpecification(status);
			return GetFilteredElements(juntasSpecification.SatisfiedBy(), junta => junta.Nombre, true);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="juntaByGuidSpecification"></param>
		/// <returns></returns>
		public Junta FindJuntaByGuidSpecification(JuntaByGuidSpecification juntaByGuidSpecification)
		{
			if (juntaByGuidSpecification == null)
				throw new ArgumentNullException("juntaByGuidSpecification");
			return GetBySpec(juntaByGuidSpecification).FirstOrDefault();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="juntasByMunicipioSpecification"></param>
		/// <returns></returns>
		public IEnumerable<Junta> FindJuntasByMunicipioSpecification(JuntasByMunicipioSpecification juntasByMunicipioSpecification)
		{
			if (juntasByMunicipioSpecification == null)
				throw new ArgumentNullException("juntasByMunicipioSpecification");
			return GetFilteredElements(juntasByMunicipioSpecification.SatisfiedBy(), junta => junta.Nombre, true);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="juntasByMunicipioSpecification"></param>
		/// <param name="status"></param>
		/// <returns></returns>
		public IEnumerable<Junta> FindJuntasByMunicipioAndStatusSpecification(JuntasByMunicipioSpecification juntasByMunicipioSpecification, bool status = true)
		{
			if (juntasByMunicipioSpecification == null)
				throw new ArgumentNullException("juntasByMunicipioSpecification");
			Specification<Junta> juntasSpecification = new TrueSpecification<Junta>();
			juntasSpecification &= juntasByMunicipioSpecification;
			juntasSpecification &= new JuntasByStatusSpecification(status);
			return GetFilteredElements(juntasSpecification.SatisfiedBy(), junta => junta.Nombre, true);
		}

		#endregion
	}
}
